<?php
namespace inis\auth\qq;

use inis\auth\qq\Oauth;

/* PHP SDK
 * @version 2.0.0
 * @author connect@qq.com
 * @copyright © 2013, Tencent Corporation. All rights reserved.
 */
// require_once(QQ_CONNECT_CLASS_PATH."Oauth.php");

/*
 * @brief QC类，api外部对象，调用接口全部依赖于此对象
 * */
class QC extends Oauth
{
    private $kesArr, $APIMap;

    /**
     * _construct
     *
     * 构造方法
     * @access public
     * @since 5
     * @param string $access_token  access_token value
     * @param string $openid        openid value
     * @return Object QC
     */
    public function __construct($access_token = "", $openid = "")
    {
        parent::__construct();
        
        // 如果access_token和openid为空，则从session里去取，适用于demo展示情形
        if ($access_token === "" || $openid === "") {
            
            $this->keysArr = [
                "oauth_consumer_key" => (int)$this->recorder->readInc("appid"),
                "access_token" => $this->recorder->read("access_token"),
                "openid" => $this->recorder->read("openid")
            ];
            
        } else $this->keysArr = [
            "openid"             => $openid,
            "access_token"       => $access_token,
            "oauth_consumer_key" => (int)$this->recorder->readInc("appid")
        ];
        
        /*
         * 初始化APIMap
         * 加#表示非必须，无则不传入url(url中不会出现该参数)， "key" => "val" 表示key如果没有定义则使用默认值val
         * 规则 array( baseUrl, argListArr, method)
         */
        $this->APIMap = [
            // qzone
            "add_blog" => [
                "https://graph.qq.com/blog/add_one_blog",
                ["title", "format" => "json", "content" => null],
                "POST"
            ],
            "add_topic" => [
                "https://graph.qq.com/shuoshuo/add_topic",
                ["richtype","richval","con","#lbs_nm","#lbs_x","#lbs_y","format" => "json", "#third_source"],
                "POST"
            ],
            "get_user_info" => [
                "https://graph.qq.com/user/get_user_info",
                ["format" => "json"],
                "GET"
            ],
            "add_one_blog" => [
                "https://graph.qq.com/blog/add_one_blog",
                ["title", "content", "format" => "json"],
                "GET"
            ],
            "add_album" => [
                "https://graph.qq.com/photo/add_album",
                ["albumname", "#albumdesc", "#priv", "format" => "json"],
                "POST"
            ],
            "upload_pic" => [
                "https://graph.qq.com/photo/upload_pic",
                ["picture", "#photodesc", "#title", "#albumid", "#mobile", "#x", "#y", "#needfeed", "#successnum", "#picnum", "format" => "json"],
                "POST"
            ],
            "list_album" => [
                "https://graph.qq.com/photo/list_album",
                ["format" => "json"]
            ],
            "add_share" => [
                "https://graph.qq.com/share/add_share",
                ["title", "url", "#comment","#summary","#images","format" => "json","#type","#playurl","#nswb","site","fromurl"],
                "POST"
            ],
            "check_page_fans" => [
                "https://graph.qq.com/user/check_page_fans",
                ["page_id" => "314416946","format" => "json"]
            ],
            // wblog
            "add_t" => [
                "https://graph.qq.com/t/add_t",
                ["format" => "json", "content","#clientip","#longitude","#compatibleflag"],
                "POST"
            ],
            "add_pic_t" => [
                "https://graph.qq.com/t/add_pic_t",
                ["content", "pic", "format" => "json", "#clientip", "#longitude", "#latitude", "#syncflag", "#compatiblefalg"],
                "POST"
            ],
            "del_t" => [
                "https://graph.qq.com/t/del_t",
                ["id", "format" => "json"],
                "POST"
            ],
            "get_repost_list" => [
                "https://graph.qq.com/t/get_repost_list",
                ["flag", "QQ_CONNECT_ROOTid", "pageflag", "pagetime", "reqnum", "twitterid", "format" => "json"]
            ],
            "get_info" => [
                "https://graph.qq.com/user/get_info",
                ["format" => "json"]
            ],
            "get_other_info" => [
                "https://graph.qq.com/user/get_other_info",
                ["format" => "json", "#name", "fopenid"]
            ],
            "get_fanslist" => [
                "https://graph.qq.com/relation/get_fanslist",
                ["format" => "json", "reqnum", "startindex", "#mode", "#install", "#sex"]
            ],
            "get_idollist" => [
                "https://graph.qq.com/relation/get_idollist",
                ["format" => "json", "reqnum", "startindex", "#mode", "#install"]
            ],
            "add_idol" => [
                "https://graph.qq.com/relation/add_idol",
                ["format" => "json", "#name-1", "#fopenids-1"],
                "POST"
            ],
            "del_idol" => [
                "https://graph.qq.com/relation/del_idol",
                ["format" => "json", "#name-1", "#fopenid-1"],
                "POST"
            ],
            // pay
            "get_tenpay_addr" => [
                "https://graph.qq.com/cft_info/get_tenpay_addr",
                ["ver" => 1,"limit" => 5,"offset" => 0,"format" => "json"]
            ]
        ];
    }

    //调用相应api
    private function _applyAPI($arr, $argsList, $baseUrl, $method)
    {
        $pre = "#";
        $keysArr = $this->keysArr;
        
        // 一些多项选填参数必选一的情形
        $optionArgList = [];
        
        foreach ($argsList as $key => $val) {
            
            $tmpKey = $key;
            $tmpVal = $val;
            
            if (!is_string($key)) {
                
                $tmpKey = $val;
                
                if (strpos($val,$pre) === 0) {
                    
                    $tmpVal = $pre;
                    $tmpKey = substr($tmpKey,1);
                    
                    if (preg_match("/-(\d$)/", $tmpKey, $res)) {
                        
                        $tmpKey = str_replace($res[0], "", $tmpKey);
                        $optionArgList[$res[1]][] = $tmpKey;
                    }
                    
                } else $tmpVal = null;
            }
            
            // 如果没有设置相应的参数
            if (!isset($arr[$tmpKey]) || $arr[$tmpKey] === "") {
                
                // 则使用默认的值
                if($tmpVal == $pre) continue;
                else if($tmpVal) $arr[$tmpKey] = $tmpVal;
                else {
                    if ($v = $_FILES[$tmpKey]) {
                        
                        $filename = dirname($v['tmp_name'])."/".$v['name'];
                        move_uploaded_file($v['tmp_name'], $filename);
                        $arr[$tmpKey] = "@$filename";
                    } else $this->error->showError("api调用参数错误","未传入参数$tmpKey");
                }
            }
            $keysArr[$tmpKey] = $arr[$tmpKey];
        }
        
        // 检查选填参数必填一的情形
        foreach ($optionArgList as $val) {
            $n = 0;
            foreach($val as $v) if (in_array($v, array_keys($keysArr))) $n ++;
            
            if (!$n) {
                $str = implode(",",$val);
                $this->error->showError("api调用参数错误",$str."必填一个");
            }
        }
        
        if ($method == "POST") {
            
            if ($baseUrl == "https://graph.qq.com/blog/add_one_blog") $response = $this->urlUtils->post($baseUrl, $keysArr, 1);
            else $response = $this->urlUtils->post($baseUrl, $keysArr, 0);
            
        } else if($method == "GET") $response = $this->urlUtils->get($baseUrl, $keysArr);
        
        return $response;
    }

    /**
     * _call
     * 魔术方法，做api调用转发
     * @param string $name    调用的方法名称
     * @param array $arg      参数列表数组
     * @since 5.0
     * @return array          返加调用结果数组
     */
    public function __call($name,$arg)
    {
        // 如果APIMap不存在相应的api
        if (empty($this->APIMap[$name])) $this->error->showError("api调用名称错误","不存在的API: <span style='color:red;'>$name</span>");
        
        // 从APIMap获取api相应参数
        $baseUrl  = $this->APIMap[$name][0];
        $argsList = $this->APIMap[$name][1];
        
        $method = isset($this->APIMap[$name][2]) ? $this->APIMap[$name][2] : "GET";
        if (empty($arg)) $arg[0] = null;
        
        // 对于get_tenpay_addr，特殊处理，php json_decode对\xA312此类字符支持不好
        if ($name != "get_tenpay_addr") {
            
            $response    = json_decode($this->_applyAPI($arg[0], $argsList, $baseUrl, $method));
            $responseArr = $this->objToArr($response);
            
        } else $responseArr = $this->simple_json_parser($this->_applyAPI($arg[0], $argsList, $baseUrl, $method));
        
        // 检查返回ret判断api是否成功调用
        if ($responseArr['ret'] == 0) return $responseArr;
        else $this->error->showError($response->ret, $response->msg);
    }

    // php 对象到数组转换
    private function objToArr($obj)
    {
        if (!is_object($obj) && !is_array($obj)) return $obj;
        
        $arr = [];
        
        foreach($obj as $k => $v) $arr[$k] = $this->objToArr($v);
        
        return $arr;
    }


    /**
     * get_access_token
     * 获得access_token
     * @param void
     * @since 5.0
     * @return string 返加access_token
     */
    public function get_access_token()
    {
        return $this->recorder->read("access_token");
    }

    // 简单实现json到php数组转换功能
    private function simple_json_parser($json)
    {
        $json      = str_replace("{","",str_replace("}","", $json));
        $jsonValue = explode(",", $json);
        
        $arr = [];
        
        foreach($jsonValue as $v) {
            $jValue = explode(":", $v);
            $arr[str_replace('"',"", $jValue[0])] = (str_replace('"', "", $jValue[1]));
        }
        
        return $arr;
    }
}
